package szkeleton;

import java.awt.Point;

import szkeleton.Gamelogic.Direction;

public class Tile {
	private Puzzle thePuzzle;
	private	Element[][] bitmap;
	private Point spawnPoint;
	
	
	public Point getSpawnPoint(){
		if(Controller.isDebug()) System.out.println("Tile.getSpawnPoint()");
		return spawnPoint;
	}
	
	public Tile(Puzzle pu, char[][] charmap, int containsPlayer){
		if(charmap != null)
		{
			
			//a bitmap meretenek meghatarozasa charmap dimenziojabol
			this.bitmap = new Element[charmap.length][charmap[0].length];
			
			thePuzzle=pu;
			
			//a bitmap feltoltese
			//lofasz
			for(int i = 0; i < charmap.length; i++)
			{	
				for(int j = 0; j < charmap[i].length; j++){
					
					if (Controller.isDebug())System.out.println(charmap[i][j]);
					if (Controller.isDebug())System.out.println(j);
					switch (charmap[i][j])
					{
					case 'x':
						bitmap[i][j] = new BlackPoint();
						break;
					case 'd':
						bitmap[i][j] = new Door();
						break;
					case 'o':
						bitmap[i][j] = new WhitePoint();
						break;
					case 'k':
						bitmap[i][j] = new Key();
						break;
					case 'a':
						bitmap[i][j] = new Door();
						break;
						
					case 's':
						bitmap[i][j] = new WhitePoint();
						//player letrehoza ha ebben a tile-ban van
						/*if( containsPlayer != -1 )
						{
							Gamelogic.setPlayer(new Player(this, new Point(j,i)), containsPlayer);
						} */
						switch (containsPlayer)
						{
						case 0:
							Gamelogic.setPlayer(new Player(this, new Point(j,i)), 0);
							break;
						case 1:
							Gamelogic.setPlayer(new Player(this, new Point(j,i)), 1);
							break;
						case 2:
							Gamelogic.setPlayer(new Player(this, new Point(j,i)), 0);
							Gamelogic.setPlayer(new Player(this, new Point(j,i)), 1);
							break;
						}
						
						spawnPoint = new Point(j,i);
						break;
					default: if(Controller.isDebug()) System.out.println("nem megfelelo karakter");
					}
				}
			}
			if(Controller.isDebug()) System.out.println("Tile konsturtor");
		}else if(Controller.isDebug()) System.out.println("EmptyTile konstruktor");
	}
	
	public Element getElement(Point bitmapIndex, Player caller)
	{	
		try
		{
		return bitmap[bitmapIndex.y][bitmapIndex.x];
		}
		catch (ArrayIndexOutOfBoundsException e){			//detektalja ha kilep a tile-bol
			Direction dir = Direction.east;
			
			if(bitmapIndex.x < 0) dir = Direction.west;
			if(bitmapIndex.x >= bitmap[0].length) dir = Direction.east;
			if(bitmapIndex.y < 0) dir = Direction.north;
			if(bitmapIndex.y >= bitmap.length) dir = Direction.south;
			
			try
			{
			Tile neighbour = thePuzzle.getNeighbour(dir, this);
			if (this.isCompatible(dir, neighbour))
			{
				//player pointToGo-ja itt kerul modositasra, hogy a masik tile-ba mar benne legyen
				switch (dir)
				{
					case east:	bitmapIndex.x = 0; 					break;
					case west:	bitmapIndex.x = bitmap[0].length-1; 	break;
					case north:	bitmapIndex.y = bitmap.length-1; break;
					case south:	bitmapIndex.y = 0; 					break;
					default:	break;
				}
				caller.setPointToGo(bitmapIndex);
				caller.setNewOwner(neighbour);
				return neighbour.getElementforView(bitmapIndex);
			}
			else
			{
//				//ha nem kompatibilis akkor helyben marad vagy meghal ha alul esett ki
//				//alul esett ki?
//				if (dir == Direction.south) return new DieElement();
//				//mas olyan mintha falnak ment volna
				if (dir == Direction.south) return new DieElement();
				return new BlackPoint();
				
			}
			}catch(ArrayIndexOutOfBoundsException exc)
			{
				if (dir == Direction.south) return new DieElement();
				return new BlackPoint();
			}
		}
		
	}
	
	public Element getElementforView(Point p)
	{
		return bitmap[p.y][p.x];
	}
	
	public boolean isOnGap(Point pl){
		
		if (pl.y + 1 >= bitmap.length)	return true;				//ha a legalso sorban all, akkor az gap (essen ki)
		
		try
		{
			Element underPl = bitmap[pl.y+1][pl.x];
			return underPl.isCompatible(new WhitePoint());			//ha alatta olyan Element van ami kompatibilis a feherrel akkor ez gap
		}
		catch (Exception e){
			;
		}
		
		return false;												//ha tenyleges poziciojara hivjak meg a playernek akkor ez nem futhat le
	}
	
	//a dir a tile belso pontja felol mutat a szelere 
	public Element[] getEdge(Direction dir){
		if (this.isEmpty()) return null;
		//ha a bitmapbol sort ker, vagyis a kepernyon oszlopot
		if (dir == Gamelogic.Direction.north) return bitmap[0];
		if (dir == Gamelogic.Direction.south) return bitmap[bitmap.length-1];
		
		//ha a bitmapbol oszlopot ker, vagyis a kepernyon sort
		int x = 0;
		if (dir == Gamelogic.Direction.east) x = bitmap[0].length-1;
		if (dir == Gamelogic.Direction.west) x = 0;
		
		Element[] edge = new Element[bitmap.length];
		for(int y = 0; y < edge.length; y++)
		{
			edge[y] = bitmap[y][x];
		}
		
		return edge;
	}
	
	
	
	public boolean isCompatible(Direction dir, Tile neighbour){
		Direction inner;
		//Ellentetes iranyu oldalat kell lekerni annak, akibe at akarok menni
		switch(dir)
		{
			case east:	inner = Direction.west;		break;
			case west:	inner = Direction.east;		break;
			case north:	inner = Direction.south;	break;
			case south:	inner = Direction.north;	break;
			default:	inner = Direction.east;
		}
		Element[] thisEdge		= this.getEdge(dir);					//sajat szele
		Element[] neighbourEdge	= neighbour.getEdge(inner);				//szomszed szele
		
		if (neighbourEdge==null) return false;
		
		for(int i = 0; i < thisEdge.length; i++)						//ha valahol nem kompatibilis az element..
		{																//nem mehet at.
			if( !(thisEdge[i].isCompatible(neighbourEdge[i])) ) return false;
		}
		return true;
	}
	
	public Tile(Tile source)
	{
		this.thePuzzle = source.thePuzzle;
		this.spawnPoint = (Point) source.spawnPoint.clone();
		this.bitmap = source.bitmap.clone();
	}
	
	public String getContentRow(int Index)
	{
		char[] content = new char[bitmap[Index].length];
		for(int j = 0; j < bitmap[Index].length; j++)
			{
			switch(bitmap[Index][j].getTipe())
			{
				case wp:	content[j] = 'o'; break;
				case bp:	content[j] = 'x'; break;
				case d:		content[j] = 'd'; break;
				case k:		if (!((Key)bitmap[Index][j]).isTaken())
								content[j] = 'k';
							else 
								content[j]='o'; 
							break;
				default:	System.out.println("Szar van a palacsintaban");
			}
		}
		return new String(content);
	}
	
	public Point getDimension(){
		return new Point(bitmap[0].length, bitmap.length);
	}
	public boolean isEmpty(){
		return false;
	}
	
}

